package main

import (
	"encoding/json"
	"fmt"
)

type Data struct {
	ID       int64
	ParentId int64
	Name     string
}
type Tree struct {
	ID       int64
	ParentId int64
	Name     string
	Children []*Tree
}

func main() {
	var data = make([]*Data, 0)
	data = append(data, []*Data{
		&Data{1, 0, "1"},
		&Data{2, 0, "2"},
		&Data{3, 0, "3"},
		&Data{4, 1, "4"},
		&Data{5, 4, "5"},
		&Data{6, 5, "6"},
		&Data{7, 6, "7"},
		&Data{8, 7, "8"},
		&Data{9, 8, "9"},
		&Data{10, 9, "10"},
	}...)

	tree := GetTree(data)
	marshal, _ := json.Marshal(&tree)
	fmt.Println(string(marshal))
}

func GetTree(data []*Data) []*Tree {
	var tree = make([]*Tree, 0)
	for _, v := range data {
		if v.ParentId != 0 {
			continue
		}
		parent := Tree{
			ID:       v.ID,
			ParentId: v.ParentId,
			Name:     v.Name,
		}
		res := findChildren(&parent, data)
		tree = append(tree, res)
	}
	return tree
}

func findChildren(parent *Tree, data []*Data) *Tree {
	var res = make([]*Tree, 0)
	for _, v := range data {
		if v.ParentId != parent.ID {
			continue
		}
		child := &Tree{
			ID:       v.ID,
			ParentId: v.ParentId,
			Name:     v.Name,
			Children: []*Tree{},
		}
		res = append(res, findChildren(child, data))
	}
	parent.Children = res
	return parent
}
